package com.xiangxiao.rpan.storage.download.channelAndBuffer;

import com.xiangxiao.rpan.storage.core.DownloadFileTool;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.MappedByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;

/**
 * @auther xiangxiao
 * @email 573768011@qq.com
 * @data 2023/12/1 17:41
 */
@Component(value = "downloadFileChannelAndByteBuffer")
public class DownloadFileChannelAndByteBuffer implements DownloadFileTool {
  @Override
  public void readStreamToFile(String path, HttpServletResponse response) throws FileNotFoundException {
    RandomAccessFile randomAccessFile = null;
    FileChannel fileChannel = null;
    InputStream inputStream = null;
    try {
      File file = new File(path);
      long downloadSize = file.length();
      inputStream = new FileInputStream(path);
      //注意下面设置的相关请求头
      response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
      //相当于设置请求头content-length
      response.setContentLengthLong(downloadSize);

      //使用URLEncoder处理中文名(否则会出现乱码)
      response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
      randomAccessFile = new RandomAccessFile(file,"rw");

      fileChannel = randomAccessFile.getChannel();

      long size = fileChannel.size();

      MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE,0,size);

      WritableByteChannel outChannel = Channels.newChannel(response.getOutputStream());
      byte[] buffer=new byte[1024*4];
      int len;
      while((len = inputStream.read(buffer))!=-1){
        mappedByteBuffer.put(buffer,0,len);
        outChannel.write(mappedByteBuffer);
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }finally {
      try {
        if(inputStream!=null) {
          inputStream.close();
        }
        if(fileChannel!=null){
          fileChannel.close();
        }
        if(randomAccessFile!=null){
          randomAccessFile.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

  }

  @Override
  public String convertMuitlFileToStream(MultipartFile multipartFile, Integer chunkNumber, Integer totalChunks, long blockSize) {
    // todo
    return null;
  }
}
